import React, { useState, useEffect } from 'react'
import { Form, message, Modal, Icon, Tree, Input, Row, Col, Checkbox, Spin } from 'antd'
import { size } from 'lodash';
import classnames from 'classnames';

import { isSuccess } from '@/utils/request';
import If from '@/components/If';

import { orgService } from '@/services/salaryManage/orgService';

import styles from '../style.less'

const { Search } = Input

const { TreeNode } = Tree;

// 搜索过滤
const rebuildData = (value, arr) => {
    const newArr = [];
    arr.forEach(element => {
    if (element.children && element.children.length) {
      const ab = rebuildData(value, element.children);
      const obj = {
        ...element,
        children: ab
      };
      if (element.title.indexOf(value) > -1 || (ab && ab.length)) {
        newArr.push(obj);
      }
    } else if (element.title.indexOf(value) > -1) {
        newArr.push(element);
      }
  });
  return newArr;
};

// 选中
const getCheckData = (list, checkArr) => {
    const resArr = []

    const recursiveFn = data => data.forEach(ele => {
        const { children, value, ...otherProps } = ele
        if (checkArr.includes(value)) {
            resArr.push({
                ...otherProps,
                value
            })
        }
        if (children && children.length) {
            recursiveFn(children)
        }
    })
    recursiveFn(list)
  return resArr;
};

// 包含下级时，过滤选值
const excludeSelect = (selectArr, nodeTree = []) => {
    if (selectArr.length < 2) {
        return selectArr
    }
    const selectList = selectArr.slice()

    const recursionFn = nodeList => {
        nodeList.forEach(({ props }) => {
            const { selectable, dataRef, children } = props
            if (selectable) {
                const index = selectList.findIndex(item => item === dataRef.key)
                selectList.splice(index, 1)
                if (children && children.length) {
                    recursionFn(children)
                }
            }
        })
    }

    recursionFn(nodeTree)

    return selectList
}

// 切换包含下级时重置选值
const initCheckList = (checkList, treeList) => {
    if (checkList.length < 2) {
        return checkList
    }
    const selectList = checkList.slice()

    const cancelSelectFn = (dataList, type = false) => {
        dataList.forEach(({ key, children = [] }) => {
            if (type && selectList.includes(key)) {
                selectList.splice(selectList.findIndex(item => item === key), 1)
                cancelSelectFn(children, true)
            } else if (selectList.includes(key)) {
                cancelSelectFn(children, true)
            } else {
                cancelSelectFn(children, type)
            }
        })
    }

    cancelSelectFn(treeList)
    return selectList
}

// 组织机构树
const DepartmentTree = ({ checkStrictly, checkList, setCheckList, setCheckItemList, searchVal }) => {
    const [loading, setLoading] = useState(false)
    const [departmentList, setDepartmentList] = useState([])

    useEffect(() => {
        setCheckItemList(getCheckData(departmentList, checkList))
    }, [checkList])

    useEffect(() => {
        if (checkStrictly && departmentList.length) {
            setCheckList(initCheckList(checkList, departmentList))
        }
    }, [checkStrictly])

    useEffect(() => {
        const init = async () => {
            setLoading(true)
            const departmentReq = await orgService.queryOrganizationTreeList()
            setLoading(false)
            if (isSuccess(departmentReq)) {
                const tempData = departmentReq?.data;
                if (size(tempData)) {
                    // 树数据转换
                    const preprocessDataItem = array =>
                        array?.map(item => {
                            const obj = item;

                            if (obj?.children?.length) {
                                obj.children = preprocessDataItem(obj.children);
                            }
                            if ((obj.organizationType === 1 || obj.organizationType === 2)) {
                                // 组织机构下不能选择集团和公司
                                obj.checkable = false;
                                obj.selectable = false;
                            }

                            return {
                                checkable: true,
                                ...obj,
                                value: obj.organizationCode,
                                title: obj.organizationName,
                                key: obj.organizationCode
                            };
                        });
                    const arr = preprocessDataItem(tempData);
                    setDepartmentList(arr)
                    setCheckItemList(getCheckData(arr, checkList))
                }
            } else {
                message.error(departmentReq.msg)
            }
        }
        init()
    }, [])

    const changeTree = (checkedKeys, e) => {
        const { checked, node } = e;
        setCheckList((checkStrictly && checked) ?
            excludeSelect(checkedKeys.checked, node.props.children) : checkedKeys.checked)
    }

    const treeList = (searchVal && rebuildData(searchVal, departmentList)) || departmentList;

    const TreeNodeTitle = ({ title, deleteFlag }) => (
        <div>{title}<span style={{ color: 'red' }}>{deleteFlag === 1 ? '（已删除）' : ''}</span></div>
    )

    const renderTreeNodes = (data, disabled = false) =>
        data.map(item => {
            const checkAble = checkList.includes(item.key)
            if (item.children) {
                return (
                    <TreeNode
                        checkable={item.checkable}
                        selectable={checkAble}
                        title={<TreeNodeTitle {...item} />}
                        key={item.key}
                        disableCheckbox={disabled}
                        dataRef={item}>
                        {renderTreeNodes(item.children, disabled || (checkAble && checkStrictly))}
                    </TreeNode>
                );
            }
            return (
                <TreeNode
                    checkable={item.checkable}
                    selectable={checkAble}
                    title={<TreeNodeTitle {...item} />}
                    key={item.key}
                    disableCheckbox={disabled}
                    {...item}
                    dataRef={item} />
            );
        }
        );

    return (
        <Spin spinning={loading}>
            {
                treeList.length ? (
                    <Tree
                        checkStrictly
                        autoExpandParent
                        defaultExpandAll
                        multiple
                        checkable
                        onCheck={changeTree}
                        checkedKeys={checkList}
                    >
                        {renderTreeNodes(treeList)}
                    </Tree>
                ) : null
            }
        </Spin>
    )
}

// 右侧选择Wrapper
const ChooseWrapper = ({ chooseList, delFn }) => {
    const delHandle = key => {
        delFn(key)
    }
    return (
        chooseList?.map(item => (
            <div className={styles.orgChooseItem} key={item.key}>
                <span>{item.title}<em style={{ color: 'red', fontStyle: 'normal' }}>{item.deleteFlag === 1 ? '（已删除）' : ''}</em></span>
                <i className={classnames('icon', 'iconfont', 'iconcancel_o', styles.delIcon)}
                    onClick={() => delHandle(item.value)}></i>
            </div>
        ))
    )
}

const DepartmentSettingModal = Form.create()(({
    visible,
    onOk,
    organizationCode,
    departmentList,
    isContainSubOrg,
    onCancel }) => {
    const [include, setInclude] = useState(false)
    const [searchVal, setSearchVal] = useState('')
    const [checkList, setCheckList] = useState([])
    const [checkItemList, setCheckItemList] = useState([])

    useEffect(() => {
       setCheckList(departmentList)
    }, [departmentList])

    useEffect(() => {
        setInclude(Boolean(isContainSubOrg))
    }, [isContainSubOrg])

    // 包含下级部门事件
    const changeInclude = e => {
        setInclude(e.target.checked)
    }

    // 切换搜索条件
    const onchangeSearchFn = e => {
        setSearchVal(e.target.value)
    }

    // 删除选中
    const delChooseFn = key => {
        setCheckList(checkList.filter(item => item !== key))
    }

    const checkBol = checkList.length > 10

    const saveFn = () => {
        if (checkBol) {
            message.error('最多只能选10个组织机构')
            return
        }
        onOk(checkList, include)
    }

    return (
        <Modal
            title="选择组织机构"
            visible={visible}
            okText="确定"
            onOk={saveFn}
            cancelText="取消"
            onCancel={onCancel}
            width={826}
    >
            <div className={styles.orgTreeBody}>
                <Row className={styles.orgTreeContain}>
                    <Col span={12}>
                        <div className={
                            classnames(styles.orgTreeLeftSide, checkBol ? styles.beyondChoose : null)
                        }>
                            <Search placeholder="搜索组织机构名称" onChange={onchangeSearchFn} />
                            <div className={styles.includeBox}>
                                <Checkbox checked={include} onChange={changeInclude}>包含下级部门</Checkbox>
                            </div>
                            <div className={styles.orgTreeMain}>
                                <DepartmentTree
                                    checkList={checkList}
                                    checkStrictly={include}
                                    searchVal={searchVal}
                                    setCheckList={setCheckList}
                                    setCheckItemList={setCheckItemList}
                                    organizationCode={organizationCode} />
                            </div>
                            {
                                checkBol ? (
                                    <div className={styles.redInfo}>最多只能选10个组织机构</div>
                                ) : null
                            }
                        </div>
                    </Col>
                    <Col span={12}>
                        <div className={styles.orgTreeRightChoose}>
                            <p className={styles.title}>已选：{checkItemList.length}</p>
                            <div className={styles.orgTreeMain}>
                                <ChooseWrapper
                                    delFn={delChooseFn}
                                    chooseList={checkItemList} />
                            </div>
                        </div>
                    </Col>
                </Row>
            </div>
        </Modal>
        )
    });
DepartmentSettingModal.displayName = 'DepartmentSettingModal';

/**
 *总览配置
 * @param organizationCode
 * @param globalInfo
 * @param changeFn
 */
const useDepartmentTree = (departmentCodeList = [], organizationCode, isContainSubOrg, changeFn) => {
    // 显示分配
    const [showDepartmentSetting, setShowDepartmentSetting] = useState(false);
    const [departmentList, setDepartmentList] = useState([]);

    // 展示弹窗
    const onShowDepartmentSetting = () => {
        setDepartmentList(JSON.parse(JSON.stringify(departmentCodeList)))
        setShowDepartmentSetting(true);
    };
    // 保存按钮
    const onTotalSetting = (list, include) => {
        changeFn(list, include)
        setShowDepartmentSetting(false)
    };

    return {
        onShowDepartmentSetting,
        render() {
            return (
                <>
                    <div className={styles.orgSelectTree} onClick={onShowDepartmentSetting}>
                        <span>组织机构</span>
                        <Icon className={styles.orgSelectDownIcon} type="down" />
                    </div>
                    <If condition={showDepartmentSetting}>
                        <DepartmentSettingModal
                            visible={showDepartmentSetting}
                            onOk={onTotalSetting}
                            organizationCode={organizationCode}
                            isContainSubOrg={isContainSubOrg}
                            onCancel={() => setShowDepartmentSetting(false)}
                            departmentList={departmentList}
                        />
                    </If>
                </>
            );
        }
    };
};

export default useDepartmentTree;
